#include "data2nvs.h"
#define NVS_TAG "nvs_storage"
//nvs flash init
esp_err_t data2nvs_init(void)
{
    esp_err_t err  = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_LOGE(NVS_TAG, "NVS partition was truncated and needs to be erased");
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_LOGI(NVS_TAG, "NVS init done");
    return err;
}

//温湿度数据的第一次启动(写操作)
esp_err_t write_first_data_boot_flag(bool is_first_boot)
{
    nvs_handle nvs_handle_t;
    esp_err_t err = nvs_open(TEMP_HUMI_STORAGE, NVS_READWRITE, &nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to open NVS handle! Error: %d", err);
        return err;
    }

     err = nvs_set_blob(nvs_handle_t,"first_data_key", &is_first_boot,sizeof(is_first_boot));
    if(err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to write first boot flag to NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }
    err = nvs_commit(nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to commit changes to NVS! Error: %d", err);
    }

    nvs_close(nvs_handle_t);
    return ESP_OK;
}


//温湿度数据的第一次启动(读操作)
esp_err_t read_first_data_boot_flag(bool *is_first_boot)
{
    nvs_handle nvs_handle_t;
    esp_err_t err = nvs_open(TEMP_HUMI_STORAGE, NVS_READONLY, &nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to open NVS handle! Error: %d", err);
        return err;
    }

    size_t required_size = sizeof(bool);
    err = nvs_get_blob(nvs_handle_t, "first_data_key", is_first_boot, &required_size);
    if(err == ESP_ERR_NVS_NOT_FOUND)
    {
        *is_first_boot = true;
    }
    else if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to read first boot flag from NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }
    nvs_close(nvs_handle_t);
    return ESP_OK;
}


//  write_data_to_nvs 和 read_data_from_nvs 函数
esp_err_t write_data_to_nvs(float max_temp, float min_temp, float max_humi, float min_humi,float low_power) 
{
    nvs_handle nvs_handle_t;
    esp_err_t err = nvs_open(TEMP_HUMI_STORAGE, NVS_READWRITE, &nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to open NVS handle! Error: %d", err);
        return err;
    }

    // 存储温湿度上下限
    err = nvs_set_blob(nvs_handle_t, "max_temp", &max_temp, sizeof(max_temp));
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to write max_temp to NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

    err = nvs_set_blob(nvs_handle_t, "min_temp", &min_temp, sizeof(min_temp));
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to write min_temp to NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

    err = nvs_set_blob(nvs_handle_t, "max_humi", &max_humi, sizeof(max_humi));
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to write max_humi to NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

    err = nvs_set_blob(nvs_handle_t, "min_humi", &min_humi, sizeof(min_humi));
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to write min_humi to NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

    err = nvs_set_blob(nvs_handle_t, "low_power", &low_power, sizeof(low_power));
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to write low_power to NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

    err = nvs_commit(nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to commit changes to NVS! Error: %d", err);
    }

    nvs_close(nvs_handle_t);
    return err;
}

esp_err_t read_data_from_nvs(float *max_temp, float *min_temp, float *max_humi, float *min_humi,float *low_power) {
    nvs_handle nvs_handle_t;
    esp_err_t err = nvs_open(TEMP_HUMI_STORAGE, NVS_READONLY, &nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to open NVS handle! Error: %d", err);
        return err;
    }

    size_t required_size = sizeof(float);
    err = nvs_get_blob(nvs_handle_t, "max_temp", max_temp, &required_size);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to read max_temp from NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

    err = nvs_get_blob(nvs_handle_t, "min_temp", min_temp, &required_size);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to read min_temp from NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

    err = nvs_get_blob(nvs_handle_t, "max_humi", max_humi, &required_size);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to read max_humi from NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

    err = nvs_get_blob(nvs_handle_t, "min_humi", min_humi, &required_size);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to read min_humi from NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

     err = nvs_get_blob(nvs_handle_t, "low_power", low_power, &required_size);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to read low_power from NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

    nvs_close(nvs_handle_t);
    return ESP_OK;
}


esp_err_t write_wifi_info_to_nvs(char *ssid, char *password)
{
    // 检查输入参数是否有效
    if (ssid == NULL || password == NULL) {
        ESP_LOGE(NVS_TAG, "SSID or password is NULL!");
        return ESP_ERR_INVALID_ARG; // 参数无效
    }

    nvs_handle nvs_handle_t;
    esp_err_t err = nvs_open(WIFI_STORAGE, NVS_READWRITE, &nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to open NVS handle! Error: %d", err);
        return err;
    }

    // 存储 ssid
    err = nvs_set_blob(nvs_handle_t, "ssid", ssid, strlen(ssid) + 1); 
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to write SSID to NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }

    // 存储 password
    err = nvs_set_blob(nvs_handle_t, "password", password, strlen(password) + 1); 
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to write password to NVS! Error: %d", err);
        nvs_close(nvs_handle_t);
        return err;
    }
    
    // 提交更改
    err = nvs_commit(nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to commit changes to NVS! Error: %d", err);
    }

    // 关闭 NVS 句柄
    nvs_close(nvs_handle_t);
    return ESP_OK;
}


esp_err_t read_wifi_info_from_nvs(char *ssid, char *password)
{
    nvs_handle nvs_handle_t;
    esp_err_t err = nvs_open(WIFI_STORAGE, NVS_READONLY, &nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to open NVS handle! Error: %d", err);
        return err;
    }

    size_t ssid_size = 0;
    err = nvs_get_blob(nvs_handle_t, "ssid", NULL, &ssid_size); // 获取 ssid 数据大小
    if (err == ESP_OK && ssid_size > 0) {
        err = nvs_get_blob(nvs_handle_t, "ssid", ssid, &ssid_size); 
        if (err != ESP_OK) {
            ESP_LOGE(NVS_TAG, "Failed to read SSID from NVS! Error: %d", err);
            nvs_close(nvs_handle_t);
            return err; // 返回错误
        }
    }

    size_t password_size = 0;
    err = nvs_get_blob(nvs_handle_t, "password", NULL, &password_size); // 获取 password 数据大小
    if (err == ESP_OK && password_size > 0) {
        err = nvs_get_blob(nvs_handle_t, "password", password, &password_size); 
        if (err != ESP_OK) {
            ESP_LOGE(NVS_TAG, "Failed to read password from NVS! Error: %d", err);
            nvs_close(nvs_handle_t);
            return err; // 返回错误
        }
    }

    nvs_close(nvs_handle_t);
    return ESP_OK; // 只有在一切都成功的情况下才返回 ESP_OK
}

//重置WIFI的第一次启动标志位
esp_err_t reset_first_boot_flag() {
    nvs_handle nvs_handle_t;
    esp_err_t err = nvs_open(WIFI_STORAGE, NVS_READWRITE, &nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to open NVS handle! Error: %d", err);
        return err;
    }

    // 删除指定的 key
    err = nvs_erase_key(nvs_handle_t, "first_wifi_key");
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to erase key! Error: %d", err);
    }

    err = nvs_commit(nvs_handle_t);
    if (err != ESP_OK) {
        ESP_LOGE(NVS_TAG, "Failed to commit changes to NVS! Error: %d", err);
    }

    nvs_close(nvs_handle_t);
    ESP_LOGI(NVS_TAG,"CLEAD DONE");
    return err;
}
